package com.jabo.douban.demo.widget;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;

/**
 * 自定义TagLayout流式布局
 *
 * Author: Administrator
 * Time:   2020-03-13
 **/
public class TagLayout extends ViewGroup {

    private int mMaxLine = 1;//如果为 -1 则是不限制行数

    public TagLayout(Context context) {
        super(context);
    }

    public TagLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public TagLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    //如果要使用MarginLayoutParams,下面这两个方法必须重写，否则会出现异常
    //java.lang.ClassCastException: android.view.ViewGroup$LayoutParams cannot be cast to android.view.ViewGroup$MarginLayoutParams
    //在ViewGroup创建的过程中，如果子View没有LayoutParams会通过以下方式创建
    @Override
    protected LayoutParams generateLayoutParams(LayoutParams p) {
        return new MarginLayoutParams(p);
    }

    //这是ViewGroup在LayoutInflater中创建子View的时候创建LayoutParam的方法
    @Override
    public LayoutParams generateLayoutParams(AttributeSet attrs) {
        return new MarginLayoutParams(getContext(), attrs);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);

        int maxHeight = 0;
        int currentLine = 0;
        int lineWidth = getPaddingLeft() + getPaddingRight();
        int allHeight = getPaddingTop() + getPaddingBottom();

        int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            View childView = getChildAt(i);
            //对自view进行测量，需要进行这一步才能通过childView.getMeasuredHeight()拿出来值
            measureChildWithMargins(childView, widthMeasureSpec, 0, heightMeasureSpec, 0);
            MarginLayoutParams lp = (MarginLayoutParams) childView.getLayoutParams();
            int measuredHeight = childView.getMeasuredHeight();
            int measuredWidth = childView.getMeasuredWidth();

            //如果当前超出了父View的高度，那么换行
            if (lineWidth + measuredWidth + lp.leftMargin + lp.rightMargin > widthSize) {
                allHeight += maxHeight;
                //换行后的最大宽度默认是第一个子view的宽度，不能为0
                maxHeight = measuredHeight + lp.topMargin + lp.bottomMargin;
                lineWidth = getPaddingLeft() + getPaddingRight();
                currentLine++;
            } else {
                lineWidth += measuredWidth + lp.leftMargin + lp.rightMargin;
                maxHeight = Math.max(maxHeight, measuredHeight + lp.topMargin + lp.bottomMargin);
            }
            if (i == childCount - 1) {
                allHeight += maxHeight;
            }
            //大于了最大行就不测量了
            if (currentLine >= mMaxLine) {
                break;
            }
        }

        heightSize = heightMode == MeasureSpec.EXACTLY ? heightSize : allHeight;
        setMeasuredDimension(widthSize, heightSize);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {

        int rr;
        int bb;
        int lineWidth;
        int maxHeight = 0;
        int currentLine = 0;
        int ll = getPaddingLeft();
        int tt = getPaddingTop();
        int currentViewWidth = getMeasuredWidth();
        int childCount = getChildCount();

        for (int i = 0; i < childCount; i++) {
            View childView = getChildAt(i);
            int measuredHeight = childView.getMeasuredHeight();
            int measuredWidth = childView.getMeasuredWidth();
            MarginLayoutParams lp = (MarginLayoutParams) childView.getLayoutParams();
            int childAllWidth = measuredWidth + lp.leftMargin + lp.rightMargin;
            int childAllHeight = measuredHeight + lp.topMargin + lp.bottomMargin;

            lineWidth = ll + childAllWidth + getPaddingRight();
            if (lineWidth > currentViewWidth) {
                ll = getPaddingLeft();
                tt += maxHeight;
                currentLine++;
            }
            rr = ll + lp.leftMargin + measuredWidth;
            bb = tt + lp.topMargin + measuredHeight;
            childView.layout(ll + lp.leftMargin, tt + lp.topMargin, rr, bb);
            ll += childAllWidth;
            maxHeight = Math.max(maxHeight, childAllHeight);
            if (currentLine >= mMaxLine) {
                break;
            }
        }
    }
}
